﻿

namespace Triad.Controls
{
    using System;
    using System.Collections;
    using System.Collections.Generic;
    using System.ComponentModel;
    //using System.Text;
    using System.Web;
    using System.Web.Caching;
    using System.Web.UI;
    using System.Web.UI.WebControls;
    using System.Xml;
    public partial class tfComboBox
    {

        private string _linktfComboID = string.Empty;
        private string c_resourcePath = String.Empty;
        private string _firstItemText = String.Empty;
        private string _xdata = String.Empty;

        /// <summary>
        /// Gets the selected items.
        /// </summary>
        /// <returns></returns>
        /// <remarks>
        /// Author: tim.fischer,   8/25/2008 - 1:50 PM
        /// Modified By: 
        /// </remarks>
        [Browsable(false)]
        public string[] GetSelectedItems()
        {
            var retVal = new List<string>();

            if (String.IsNullOrEmpty(XMLtext.Text)) return null;
            var xmlDoc = new XmlDocument();
            xmlDoc.LoadXml(XMLtext.Text);
            var xmNode = xmlDoc.SelectNodes("//opt[@selected=\'true\']");
            if (xmNode != null)
            {
                int i;
                for (i = 0; i <= xmNode.Count - 1; i++)
                {
                    if (!String.IsNullOrEmpty(xmNode[i].Attributes["value"].InnerText))
                    {
                        retVal.Add(xmNode[i].Attributes["value"].InnerText);
                    }
                }
            }
            else
            {
                return null;
            }
            return retVal.ToArray();
        }

        /// <summary>
        /// Gets or sets the object from which the data-bound control retrieves its list of data items.
        /// </summary>
        /// <value></value>
        /// <returns>
        /// An object that represents the data source from which the data-bound control retrieves its data. The default is null.
        /// </returns>
        /// <remarks>
        /// Author: tim.fischer,   8/25/2008 - 1:49 PM
        /// Modified By: 
        /// </remarks>
        public override object DataSource
        {
            get
            {
                if (!IsDesignTime)
                {
                    Cache cache = HttpContext.Current.Cache;
                    return cache[ClientID + "DS"];
                }
                return base.DataSource;
            }
            set
            {
                if (!IsDesignTime)
                {
                    if (value != null)
                    {
                        Cache cache = HttpContext.Current.Cache;
                        cache[ClientID + "DS"] = value;
                    }
                }
                base.DataSource = value;

            }
        }

        public override void DataBind()
        {
            if (this.XMLtext != null) { this.XMLtext.Text = XML; }
 	         base.DataBind();
        }

        private bool IsDesignTime
        {
            get { return Site != null && Site.DesignMode; }
        }
        /// <summary>
        /// Gets or sets the type of the combo box.
        /// </summary>
        /// <value>The type of the combo box.</value>
        [Category("tfCombo"),
         DefaultValue("ReadOnly"),
        DisplayName("Combo Box Type"),
        TypeConverter(typeof(ComboTypeConverter))]
        public String ComboBoxType
        {
            get
            {
                Object cbType = ViewState[ID + "Type"];
                if (cbType != null)
                {
                    return (String)cbType;
                }
                return "ReadOnly";
            }
            set
            {
                ViewState[ID + "Type"] = value;
            }

        }

        /// <summary>
        /// Gets or sets a value indicating whether [allow auto complete].
        /// </summary>
        /// <value><c>true</c> if [allow auto complete]; otherwise, <c>false</c>.</value>
        [Category("tfCombo"),
         DefaultValue(false)]
        public bool AllowAutoComplete { get; set; }

        /// <summary>
        /// Gets or sets a value indicating whether [allow auto search].
        /// </summary>
        /// <value><c>true</c> if [allow auto search]; otherwise, <c>false</c>.</value>
        [Category("tfCombo"),
         DefaultValue(false)]
        public bool AllowAutoFilter { get; set; }

        /// <summary>
        /// Gets or sets a value indicating whether [allow multi select].
        /// </summary>
        /// <value><c>true</c> if [allow multi select]; otherwise, <c>false</c>.</value>
        [Category("tfCombo"),
         DefaultValue(false)]
        public bool AllowMultiSelect { get; set; }

        /// <summary>
        /// Gets or sets a value indicating whether [allow image].
        /// </summary>
        /// <value><c>true</c> if [allow image]; otherwise, <c>false</c>.</value>
        [Category("tfCombo"),
         DefaultValue(false)]
        public bool AllowImage { get; set; }


        /// <summary>
        /// Gets or sets the linked combo ID.
        /// </summary>
        /// <value>The linked combo ID.</value>
        [Category("tfCombo"),
         TypeConverter(typeof(ControlIDConverter)),
         IDReferenceProperty(typeof(tfComboBox)),
         Description("ID of a control on which value this validator depends.")]
        public string LinktfComboID
        {
            get { return _linktfComboID; }
            set { _linktfComboID = value; }
        }


        //[
        //Description("Gets or sets the text content of the text box portion of the ComboBox control."),
        //Category("Appearance"),
        //Bindable(true),
        //DesignerSerializationVisibility(DesignerSerializationVisibility.Visible),
        //Browsable(true),
        //]
        //public override String Text
        //{
        //    get
        //    {
        //        Object state = ViewState["Text"];
        //        if (state != null)
        //        {
        //            return (String)state;
        //        }
        //        return "";
        //    }
        //    set
        //    {
        //        ViewState["Text"] = value;
        //    }
        //}

        /// <summary>
        /// Gets or sets the XML.
        /// </summary>
        /// <value>The XML.</value>
        /// <remarks>
        /// Author: tim.fischer,   8/25/2008 - 1:40 PM
        /// Modified By: 
        /// </remarks>
        [Browsable(false)]
        public string XML
        {
            get
            {
                return FilltfCombo();
            }
            set
            {
                XMLtext.Text = FilltfCombo();
            }
        }

        /// <summary>
        /// Gets or sets the Extra data field.
        /// </summary>
        /// <value>The Extra data field.</value>
        /// <remarks>
        /// Author: tim.fischer,   8/25/2008 - 1:40 PM
        /// Modified By: 
        /// </remarks>
        [Bindable(true),
         Category("Data"),
         DefaultValue(""),
         Description("A secondary Data field to store information"),
         Localizable(true)]
        public string XtraDataField
        {
            get { return _xdata; }
            set { _xdata = value; }
        }

        private Unit c_width;
        private Unit c_dropdownwidth;
        /// <summary>
        /// Gets or sets the width of the Web server control.
        /// </summary>
        /// <value></value>
        /// <returns>
        /// A <see cref="T:System.Web.UI.WebControls.Unit"/> that represents the width of the control. The default is <see cref="F:System.Web.UI.WebControls.Unit.Empty"/>.
        /// </returns>
        /// <exception cref="T:System.ArgumentException">
        /// The width of the Web server control was set to a negative value.
        /// </exception>
        /// <remarks>
        /// Author: tim.fischer,   8/25/2008 - 1:40 PM
        /// Modified By: 
        /// </remarks>
        [
        DefaultValue(typeof(Unit), "200px"),
        ]
        public override Unit Width
        {
            get
            {
                return c_width.IsEmpty ? Unit.Pixel(200) : c_width;
            }
            set
            {
                c_width = value;
            }
        }

        /// <summary>
        /// Gets or sets the width of the drop down.
        /// </summary>
        /// <value>The width of the drop down.</value>
        /// <remarks>
        /// Author: tim.fischer,   8/25/2008 - 1:41 PM
        /// Modified By: 
        /// </remarks>
        [
            DefaultValue(typeof(Unit), "300px"),
        ]
        public Unit DropDownWidth
        {
            get
            {
                return c_dropdownwidth.IsEmpty ? Unit.Pixel(300) : c_dropdownwidth;
            }
            set
            {
                c_dropdownwidth = value;
            }
        }

        /// <summary>
        /// Gets or sets the first item text.
        /// </summary>
        /// <value>The first item text.</value>
        /// <remarks>
        /// Author: tim.fischer,   8/25/2008 - 1:41 PM
        /// Modified By: 
        /// </remarks>
        [Category("tfCombo"),
         DefaultValue("Select A Value"),
         Description("Sets the first item to a simple text"),
         Localizable(true)]
        public string FirstItemText
        {
            get
            {
                return _firstItemText;
            }
            set { _firstItemText = value; }
        }

        /// <summary>
        /// Gets or sets the resource path.
        /// </summary>
        /// <value>The resource path.</value>
        [Category("tfCombo"),
         DefaultValue("")]
        public string ResourcePath
        {
            get
            {
                if (String.IsNullOrEmpty(c_resourcePath))
                {
                    return ResolveClientUrl("~/Triad.Controls/");
                }
                if (c_resourcePath.EndsWith("/", StringComparison.CurrentCultureIgnoreCase) || c_resourcePath.EndsWith("\\", StringComparison.CurrentCultureIgnoreCase))
                {
                    return ResolveClientUrl(c_resourcePath);
                }
                return c_resourcePath + "/";
            }
            set { c_resourcePath = value; }
        }

        private string JSPath
        {
            get { return ResourcePath + "js/"; }
        }

        private string CSSPath
        {
            get { return ResourcePath + "css/"; }
        }

        private string IMGPath
        {
            get { return ResourcePath + "images/"; }
        }

        private readonly string[] PropsToRemove = {
                                                      "AccesibilityObject",
                                                      "AccessibleDescription",
                                                      "AccessibleName",
                                                      "AllowDrop",
                                                      "BackgroundImage",
                                                      "Capture",
                                                      "DisplayRectangle",
                                                      "Enabled",
                                                      "ForeColor",
                                                      "Region",
                                                      "Tag",
                                                      "Text",
                                                      "Visible"
                                                  };

        private readonly string[] EventsToRemove = {
                                                      "SelectedIndexChanged",
                                                      "TextChanged"
                                                  };


        //Does the property filtering...
        private PropertyDescriptorCollection FilterProperties(PropertyDescriptorCollection pdc)
        {
            var toRemove = new ArrayList();
            foreach (string s in PropsToRemove)
                toRemove.Add(s);

            var adjustedProps = new PropertyDescriptorCollection(new PropertyDescriptor[] { });
            foreach (PropertyDescriptor pd in pdc)
                if (!toRemove.Contains(pd.Name))
                    adjustedProps.Add(pd);

            return adjustedProps;
        }

        private EventDescriptorCollection FilterEvents(EventDescriptorCollection pdc)
        {
            var toRemove = new ArrayList();
            foreach (string s in EventsToRemove)
                toRemove.Add(s);

            var adjustedProps = new EventDescriptorCollection(new EventDescriptor[] { });
            foreach (EventDescriptor pd in pdc)
                if (!toRemove.Contains(pd.Name))
                    adjustedProps.Add(pd);

            return adjustedProps;
        }

        #region ICustomTypeDescriptor Members

        /// <summary>
        /// Gets the converter.
        /// </summary>
        /// <returns></returns>
        /// <remarks>
        /// Author: tim.fischer,   8/25/2008 - 1:43 PM
        /// Modified By: 
        /// </remarks>
        public TypeConverter GetConverter()
        {
            return TypeDescriptor.GetConverter(this, true);
        }

        /// <summary>
        /// Gets the events.
        /// </summary>
        /// <param name="attributes">The attributes.</param>
        /// <returns></returns>
        /// <remarks>
        /// Author: tim.fischer,   8/25/2008 - 1:43 PM
        /// Modified By: 
        /// </remarks>
        public EventDescriptorCollection GetEvents(Attribute[] attributes)
        {
            EventDescriptorCollection pdc = TypeDescriptor.GetEvents(this, attributes, true);
            return FilterEvents(pdc);
        }

        EventDescriptorCollection ICustomTypeDescriptor.GetEvents()
        {
            EventDescriptorCollection pdc = TypeDescriptor.GetEvents(this, true);
            return FilterEvents(pdc);
        }

        /// <summary>
        /// Gets the properties.
        /// </summary>
        /// <param name="attributes">The attributes.</param>
        /// <returns></returns>
        /// <remarks>
        /// Author: tim.fischer,   8/25/2008 - 1:43 PM
        /// Modified By: 
        /// </remarks>
        public PropertyDescriptorCollection GetProperties(Attribute[] attributes)
        {
            PropertyDescriptorCollection pdc = TypeDescriptor.GetProperties(this, attributes, true);
            return FilterProperties(pdc);
        }

        PropertyDescriptorCollection ICustomTypeDescriptor.GetProperties()
        {
            PropertyDescriptorCollection pdc = TypeDescriptor.GetProperties(this, true);
            return FilterProperties(pdc);
        }

        /// <summary>
        /// Gets the name of the component.
        /// </summary>
        /// <returns></returns>
        /// <remarks>
        /// Author: tim.fischer,   8/25/2008 - 1:43 PM
        /// Modified By: 
        /// </remarks>
        public string GetComponentName()
        {
            return TypeDescriptor.GetComponentName(this, true);
        }

        /// <summary>
        /// Gets the property owner.
        /// </summary>
        /// <param name="pd">The pd.</param>
        /// <returns></returns>
        /// <remarks>
        /// Author: tim.fischer,   8/25/2008 - 1:42 PM
        /// Modified By: 
        /// </remarks>
        public object GetPropertyOwner(PropertyDescriptor pd)
        {
            return this;
        }

        /// <summary>
        /// Gets the attributes.
        /// </summary>
        /// <returns></returns>
        /// <remarks>
        /// Author: tim.fischer,   8/25/2008 - 1:42 PM
        /// Modified By: 
        /// </remarks>
        public System.ComponentModel.AttributeCollection GetAttributes()
        {
            return TypeDescriptor.GetAttributes(this, true);
        }



        /// <summary>
        /// Gets the editor.
        /// </summary>
        /// <param name="editorBaseType">Type of the editor base.</param>
        /// <returns></returns>
        /// <remarks>
        /// Author: tim.fischer,   8/25/2008 - 1:43 PM
        /// Modified By: 
        /// </remarks>
        public object GetEditor(Type editorBaseType)
        {
            return TypeDescriptor.GetEditor(this, editorBaseType, true);
        }

        /// <summary>
        /// Gets the default property.
        /// </summary>
        /// <returns></returns>
        /// <remarks>
        /// Author: tim.fischer,   8/25/2008 - 1:43 PM
        /// Modified By: 
        /// </remarks>
        public PropertyDescriptor GetDefaultProperty()
        {
            return TypeDescriptor.GetDefaultProperty(this, true);
        }

        /// <summary>
        /// Gets the default event.
        /// </summary>
        /// <returns></returns>
        /// <remarks>
        /// Author: tim.fischer,   8/25/2008 - 1:43 PM
        /// Modified By: 
        /// </remarks>
        public EventDescriptor GetDefaultEvent()
        {
            return TypeDescriptor.GetDefaultEvent(this, true);
        }

        /// <summary>
        /// Gets the name of the class.
        /// </summary>
        /// <returns></returns>
        /// <remarks>
        /// Author: tim.fischer,   8/25/2008 - 1:43 PM
        /// Modified By: 
        /// </remarks>
        public string GetClassName()
        {
            return TypeDescriptor.GetClassName(this, true);
        }

        #endregion

   


    } //End Class
} //End Namspace
